home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / utility.lha / utility / listiter.H < prev    next >
C/C++ Source or Header  |  1993-08-08  |  5KB  |  165 lines

  1. #ifndef LISTITER_H
  2. #define LISTITER_H
  3. // This is a generic list iterator.  An iterator will sequentially go through
  4. // each element of the associated list, starting with the first element.  It is
  5. // also possible to explicitly rewind the iterator, or to move forward or
  6. // backward in the list.
  7. //
  8. // This is a protected class, i.e., it is not possible to create instances
  9. // of it.  Derived classes provide iterators for specific types of lists.
  10. // First, a new iterator type must be declared, for example, for
  11. // a list of integers:
  12. //
  13. //    ITERATOR_DECLARE(int);
  14. //
  15. // This declares a new class, called `intIterator'.
  16. // Iterator types should only be declared once.
  17. // After that, iterators of this type can be declared as needed:
  18. //
  19. //    ITERATOR(int) it(list);
  20. //
  21. // and used like this:
  22. //
  23. // .nf
  24. //    int* p;
  25. //    while( (p = it()) != nil)
  26. //        /* something */;
  27. // .fi
  28. //
  29. // To make the use of iterators easier, some macros have defined for the
  30. // most common forms.
  31. //
  32. // .SS dolist(var,list,type)
  33. // .SS enddo
  34. // The dolist-enddo construct defines a reference variable `var', an
  35. // iterator  `var_iter', and iterates through all the elements of the
  36. // list.  For example:
  37. //
  38. // .nf
  39. //    dolist(p,list,int)
  40. //      cout << p;
  41. //      p_iter.Skip(1);
  42. //    enddo;
  43. //
  44. // will print every second element of the list.
  45. //
  46. // .SS maplist(func,list,type)
  47. // Maplist can be used when a single function should be invoked on every element
  48. // of the list.  The function `func' should be of type "void func(type)", or
  49. // "void func(type &)".
  50. // Example:
  51. //
  52. //    maplist(f,list,int);
  53. //
  54. // Maplist is similar to `mapc' in Common LISP.
  55. //
  56. // .SS filterlist(src,expr,dst,type)
  57. // Filterlist will iterate trough the source list `src' and insert all
  58. // elements for which the condition `expr' is true into the destination
  59. // list `dst'.  Example:
  60. //
  61. //    filterlist(all,e == "x",xlist,String);
  62. //
  63. // The expression should return a boolean value; the name `e' denotes the
  64. // current list element in the expression.  Note that the destination list
  65. // is not automatically cleared before use.  Element order is not preserved!
  66. //
  67. // .SS printlist(ostream&,list,type,sep)
  68. // Printlist will print all elements of the list on the stream.  Each element
  69. // will be followed by the given separator.  Example:
  70. //
  71. //    printlist(cout,l,String,"\n");
  72. //
  73. // .SS Caveats
  74. // DO NOT INSERT OR REMOVE ELEMENTS IN THE ITERATED LIST!  This will result
  75. // in elements being skipped or iterated several times.  An alternative is to
  76. // move designated elements to a temporary list, and then Remove() all
  77. // members of the second list from the first list.
  78. //
  79. // DO NOT USE BLANKS WHEN CALLING MACROS!  White space is preserved in macros
  80. // and will cause compilation errors with dolist and maplist.  For example,
  81. // "maplist(func, list, int)" will fail.
  82. //
  83. // .SS Author
  84. // Dag Bruck, Department of Automatic Control, Lund Institute of Technology,
  85. // Box 118, S-221 00 Lund, Sweden (dag@control.lth.se).
  86. //
  87. // $Id: listiter.H,v 1.4 91/09/06 16:58:03 dag Exp $
  88.  
  89.  
  90. #include <defs.H>
  91. #include <list.H>
  92.  
  93.  
  94. class GenericIterator {
  95. protected:
  96.   GenericIterator(const GenericList &);
  97.   // Create iterator, starting at first element.
  98.  
  99. public:
  100.   Pointer operator () ();
  101.   // Returns next element in list, or nil at end of list.
  102.  
  103.   void Rewind();
  104.   // Rewinds iterator to first element of list.
  105.  
  106.   void Skip(int di);
  107.   // Move iterator forward or backward.  The iterator will never
  108.   // move before the first element.
  109.  
  110. private:
  111.   const GenericList& l;
  112.   unsigned i;
  113. };
  114.  
  115.  
  116. #define ITERATOR(type)NAME2(type,Iterator)
  117. #define ITERATOR_DECLARE(type)ITERATOR_DECLARE2(ITERATOR(type),type)
  118. #define ITERATOR_DECLARE2(__name,type)class __name : public GenericIterator { \
  119. public: \
  120. __name(const LIST(type)& list) : GenericIterator(list) {} \
  121. type* operator () () { return (type *) GenericIterator::operator () (); } \
  122. }
  123. #define CONSTITERATOR(type)NAME2(NAME2(const_,type),Iterator)
  124. #define CONSTITERATOR_DECLARE(type)CONSTITERATOR_DECLARE2(CONSTITERATOR(type),type)
  125. #define CONSTITERATOR_DECLARE2(__name,type)class __name : public GenericIterator { \
  126. public: \
  127. __name(const CONSTLIST(type)& list) : GenericIterator((const LIST(type)&) list) {} \
  128. const type* operator () () { return (const type *) GenericIterator::operator () (); } \
  129. }
  130.  
  131.  
  132. #define dolist(var,list,type) do { \
  133. ITERATOR(type) NAME2(var,_iter)(list);\
  134. while (true) { \
  135. register type& var = *NAME2(var,_iter)(); if (&var == nil) break;
  136. #define doconstlist(var,list,type) do { \
  137. CONSTITERATOR(type) NAME2(var,_iter)(list);\
  138. while (true) { \
  139. register const type& var = *NAME2(var,_iter)(); if (&var == nil) break;
  140. #define enddo }} while (false)
  141.  
  142. #define maplist(func,list,type) dolist(_p,list,type) func(_p); enddo
  143. #define mapconstlist(func,list,type) doconstlist(_p,list,type) func(_p); enddo
  144.  
  145. #define filterlist(src,expr,dst,type) dolist(e,src,type) if(expr)dst+=e; enddo
  146. #define filterconstlist(src,expr,dst,type) doconstlist(e,src,type) if(expr)dst+=e; enddo
  147.  
  148. #define printlist(ostr,l,type,sep) dolist(e,l,type) ostr << e << sep; enddo
  149. #define printconstlist(ostr,l,type,sep) doconstlist(e,l,type) ostr << e << sep; enddo
  150.  
  151.  
  152. inline GenericIterator :: GenericIterator(const GenericList& li)
  153.     : l(li), i(0)
  154. { }
  155.  
  156.  
  157. inline Pointer GenericIterator :: operator () ()
  158. {
  159.   register unsigned n = l.n;
  160.   return i >= n ? nil : l.p[n - i++ - 1];
  161. }
  162.  
  163.  
  164. #endif
  165.